<template>
  <div>
    <ul
      v-if="options.items"
      :id="elementId"
      class="vue-simple-context-menu2"
      v-clickoutside="onClickOutside"
      ref="contextMenu"
      :style="{
        width: options.width
      }"
    >
      <li
        v-for="(option, index) in options.items"
        :key="index"
        @click.stop="optionClicked(option)"
        class="vue-simple-context-menu2__item"
        :class="[
          option.class,
          (option.type === 'divider' ? 'vue-simple-context-menu2__divider' : ''),
          (option.children && option.children.items && option.children.items.length > 0 ? 'has-child' : '')
        ]"
      >
        <!-- 一级按钮 -->
        <div class="btn">
          <el-checkbox
            v-if="option.type === 'checkbox'"
            v-model="option.value"
            @change="(v) => _defaultConsole(v, option.changeFn)"
            >
            {{ option.name }}
          </el-checkbox>
          <template v-else-if="option.type === 'input'">
            <el-input
              class="hm-input"
              :prefix-icon="option.icon"
              v-model="option.value"
              @input="(v) => _defaultConsole(v, option.changeFn)">
            </el-input>
          </template>
          <template v-else>
            <i :class="option.icon" />
            <span class="el-checkbox__label">{{ option.name }}</span>
          </template> 
        </div>

          <!-- 二级菜单 -->
          <ul
            v-if="option.children && option.children.items && option.children.items.length > 0 "
            class="children-menu"
            :class="option.children.class"
            :data-width="option.children.width || '120px'"
            style="position: absolute;"
            :style="{
              width: option.children.width || '120px',
              left: _getChildFloat(option.children.width) === 'left' ? `-${(option.children.width || '120px')}` : '100%'
            }">
            <li
              v-for="(i, itemi) in option.children.items"
              :key="`${index}-${itemi}`"
              @click.stop="optionClicked(i)"
              class="vue-simple-context-menu2__item"
              :class="[i.class, (i.type === 'divider' ? 'vue-simple-context-menu2__divider' : '')]">

              <div class="btn">
                <el-checkbox
                  v-if="i.type === 'checkbox'"
                  v-model="i.value"
                  @change="(v) => _defaultConsole(v, i.changeFn)"
                  >
                  {{ i.name }}
                </el-checkbox>
                <template v-else-if="i.type === 'input'">
                  <el-input
                    class="hm-input"
                    size="mini"
                    :prefix-icon="i.icon"
                    v-model="i.value"
                    @input="(v) => _defaultConsole(v, i.changeFn)">
                  </el-input>
                </template>
                <template v-else>
                  <i :class="i.icon" />
                  <span class="el-checkbox__label">{{ i.name }}</span>
                </template> 
              </div>

            </li>
          </ul>

      </li>
    </ul>
  </div>
</template>

<script>
// 第三方组件 右键菜单 https://github.com/johndatserakis/vue-simple-context-menu/blob/develop/src/vue-simple-context-menu.vue
// 调整样式 ｜ 修复显示位置不准确及偶尔获取不到宽高问题

import Vue from 'vue'
import clickoutside from '@/directive/clickoutside.js'

export default {
  name: 'VueSimpleContextMenu',
  directives: {
    clickoutside,
  },
  props: {
    elementId: {
      type: String,
      required: true
    },
    options: {
      type: Object,
      default() {
        return {}
      } 
    }
  },
  data () {
    return {
      item: null,
      menuWidth: null,
      menuHeight: null,
      pageX: null,
      pageY: null,
      childrenFloat: 'float-left'
    }
  },
  methods: {
    async showMenu (event, item) {
      
      this.item = item
      this.pageX = event.pageX
      this.pageY = event.pageY

      // var menu = document.getElementById(this.elementId)
      const menu = this.$refs.contextMenu
      if (!menu) {
        return
      }

      if (!this.menuWidth || !this.menuHeight) {

        menu.style.visibility = "hidden"
        menu.style.display = "block"
        this.menuWidth = menu.offsetWidth
        this.menuHeight = menu.offsetHeight
        menu.removeAttribute("style")
        menu.style.width = this.menuWidth + 'px'
      }

      if ((this.menuWidth + event.pageX) >= window.innerWidth) {
        menu.style.left = (event.pageX - this.menuWidth + 2) + "px"
        this.childrenFloat = 'float-left'
      } else {
        menu.style.left = (event.pageX - 2) + "px"
        this.childrenFloat = 'float-right'
      }

      if ((this.menuHeight + event.pageY) >= window.innerHeight) {
        menu.style.top = (event.pageY - this.menuHeight + 2) + "px"
      } else {
        menu.style.top = (event.pageY - 2) + "px"
      }

      menu.classList.add('vue-simple-context-menu2--active')
    },
    hideContextMenu () {
      // let element = document.getElementById(this.elementId)
      const element = this.$refs.contextMenu
      if (element) {
        element.classList.remove('vue-simple-context-menu2--active');
      }
    },
    onClickOutside () {
      this.hideContextMenu()
    },
    optionClicked (option) {
      if (option.type === 'checkbox' || option.type === 'input') {
        return this.$emit('option-clicked', {
          item: this.item,
          option: option
        })
      }
      this.hideContextMenu()
      this.$emit('option-clicked', {
        item: this.item,
        option: option
      })
    },
    onEscKeyRelease (event) {
      if (event.keyCode === 27) {
        this.hideContextMenu();
      }
    },
    _getChildFloat(childWidth) {
      let _cwidth = childWidth || '120px'
      _cwidth = Number(_cwidth.replace('px', ''))
      if ((this.menuWidth + this.pageX + _cwidth) >= window.innerWidth) {
        return 'left'
      } else {
        return 'right'
      }
    },
    _defaultConsole(v, fn) {
      fn ? fn(v) : console.log(v)
    }
  },
  mounted () {
    document.body.addEventListener('keyup', this.onEscKeyRelease);
  },
  beforeDestroy () {
    document.removeEventListener('keyup', this.onEscKeyRelease);
  }
}
</script>

<style lang="scss">
$light-grey: #fff;
$grey: #e9e9e9;
$blue: #007aff;
$white: #fff;
$black: #666;

.vue-simple-context-menu2 {
  top: 0;
  left: 0;
  margin: 0;
  padding: 0;
  display: none;
  list-style: none;
  position: fixed;
  z-index: 1000000;
  background-color: $light-grey;
  border: 1px solid $grey;
  // border-bottom-width: 0px;
  // font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
  //   "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
  //   sans-serif;
  // box-shadow: 0 3px 6px 0 rgba($black, 0.2);
  border-radius: 2px;

  &--active {
    display: block;
  }

  &__item {
    display: flex;
    color: $black;
    cursor: pointer;
    align-items: center;
    font-size: 14px;

    padding: 8px;

    // &:hover {
    //   background-color: $blue;
    //   color: $white;
    // }

    .children-menu {
      display: none;
    }
    &:hover.has-child > .children-menu {
      display: block;
    }

    .btn {
      .el-checkbox__label {
        color: $black;
        font-weight: 400;
      }

      .hm-input {
        
        .el-input__inner {
          border: none;
          padding-left: 50px;
        }
        .el-input__prefix {
          border-right: 1px solid #e9e9e9;
          width: 36px;
          left:0;
        }
      }
    }

    .filter-input {
      padding: 0;
      margin: 0;
      margin-top: 0 !important;
      margin-bottom: 0 !important;
      input {
        height: 38px;
        line-height: 38px;
        margin-top:2px;
      }
    }
  }

  &__divider {
    height: 1px;
    padding: 0;
    background-color: $grey;
    pointer-events: none;
  }

  // Have to use the element so we can make use of `first-of-type` and
  // `last-of-type`
  li {
    &:first-of-type {
      margin-top: 4px;
    }

    &:last-of-type {
      margin-bottom: 4px;
    }
  }

  .has-child {
    position: relative;

    .children-menu {
      background-color: $light-grey;
      border: 1px solid $grey;
      border-radius: 4px;
      margin-top:2px;
      margin-left:1px;
    }
  }
}
// .iconfont{font-size: 16px!important;}
</style>